package org.example.auth.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.example.auth.model.entity.Role;
import org.example.auth.model.entity.User;
import org.example.auth.model.entity.UserRole;
import org.example.auth.repository.RoleRepository;
import org.example.auth.repository.UserRepository;
import org.example.auth.repository.UserRoleRepository;
import org.example.misc.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.domain.Example;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.UUID;

@Slf4j
@Component
public class AdminAuthInitService implements CommandLineRunner {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private AuthParamsConfig authParamsConfig;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void run(String... args) throws Exception {
        User user = new User();
        user.setLoginName("admin");
        List<User> users = userRepository.findAll(Example.of(user));
        if (CollectionUtils.isEmpty(users)) {
            user.setNickName("admin");
            user.setCode(UUID.randomUUID().toString());
            user.setPassword(encryptPassword("admin"));
            user.setRealName("admin");
            user = userRepository.save(user);
        } else {
            user = users.get(0);
        }
        Role role = new Role();
        role.setCode("00000");
        List<Role> roles = roleRepository.findAll(Example.of(role));
        if (CollectionUtils.isEmpty(roles)) {
            role.setName("超级管理员");
            role = roleRepository.save(role);
        } else {
            role = roles.get(0);
        }
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(role.getId());
        userRole.setDefaultFlag(Boolean.TRUE);
        List<UserRole> userRoles = userRoleRepository.findAll(Example.of(userRole));
        if (CollectionUtils.isEmpty(userRoles)) {
            userRoleRepository.save(userRole);
        } else {
            userRole = userRoles.get(0);
        }
        // 用户角色权限缓存
        redisTemplate.opsForSet().add(Constant.REDIS_USER_ROLE_PREFIX + user.getId(), role.getId().toString());
        redisTemplate.opsForSet().add(Constant.REDIS_ROLE_ROUTE_PREFIX + role.getId(), "*");
    }

    /**
     * 密码加密
     * Base64(password + md5Secret) -> md5
     */
    private String encryptPassword(String password) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new ServiceException("01500", "服务异常！");
        }
        return Hex.encodeHexString(md.digest(Base64.decodeBase64(password + authParamsConfig.getMd5Secret())));
    }
}
